#include "functions.h"

// --------------------- 打印迷宫和玩家位置的函数 ---------------------
void printMap() {
    for (int i = 0; i < MAZESIZE; i++) {
        for (int j = 0; j < MAZESIZE; j++) {
            // 如果当前位置为玩家，则打印 'P'
            if (i == player_x && j == player_y) {
                printf(":)");
            } else {
                // 这里用 "口" 表示墙，用 "<><>" 表示通路
                if (maze[i][j] == 1) {
                    printf("口");
                } else {
                    printf("  ");
                }
            }
        }
        printf("\n");
    }
}

// --------------------- 持续显示地图和玩家位置，倒计时 2 分钟 ---------------------
void showMap() {
    time_t start = time(NULL);  // 获取开始时间
    while (difftime(time(NULL), start) < timeLimit) {  // 120 秒，即 2 分钟
        // 清屏（根据平台选择命令）
        #ifdef _WIN32
                system("cls");
        #else
                system("clear");
        #endif

        printMap();

        // 计算剩余时间并打印
        int remaining = timeLimit - (int)difftime(time(NULL), start);
        printf("\nTime remaining: %d seconds\n", remaining);

        // 每次循环暂停 1 秒
        #ifdef _WIN32
                Sleep(100);
        #else
                sleep(0.1);
        #endif

            // 走到终点时退出程序
        if (player_x == exitRow && player_y == exitCol) {
            printf("顺利通关！\n");
            player_x = init_x; // 位置复位到起点
            player_y = init_y;
            // 释放内存
            for (int i = 0; i < MAZESIZE; i++) {
                free(maze[i]);
            }
            free(maze);
            
            break;
        }
    }

    if (difftime(time(NULL), start) >= timeLimit) {
        printf("时间耗尽\n");
        player_x = init_x; // 位置复位到起点
        player_y = init_y;
        // 释放内存
        for (int i = 0; i < MAZESIZE; i++) {
            free(maze[i]);
        }
        free(maze);
    }
}

// --------------------- 设置非阻塞键盘检测：检查是否有按键按下 ---------------------
int kbhit(void) {
    struct termios oldt, newt;
    int ch;
    int oldf;

    // 获取当前终端设置
    tcgetattr(STDIN_FILENO, &oldt);
    newt = oldt;
    // 禁用规范模式和回显
    newt.c_lflag &= ~(ICANON | ECHO);
    tcsetattr(STDIN_FILENO, TCSANOW, &newt);
    // 设置非阻塞模式
    oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
    fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);

    ch = getchar();

    // 恢复终端设置
    tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
    fcntl(STDIN_FILENO, F_SETFL, oldf);

    if (ch != EOF) {
        ungetc(ch, stdin);
        return 1;
    }
    return 0;
}

// --------------------- 获取一个字符（不需要回车确认） ---------------------
int getch(void) {
    struct termios oldt, newt;
    int ch;
    tcgetattr(STDIN_FILENO, &oldt);
    newt = oldt;
    // 关闭规范模式与回显
    newt.c_lflag &= ~(ICANON | ECHO);
    tcsetattr(STDIN_FILENO, TCSANOW, &newt);
    ch = getchar();
    tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
    return ch;
}

// --------------------- 持续监听键盘输入，通过 wsad 控制玩家位置 ---------------------
void controlPlayer(void) {
    while (1) {
        if (kbhit()) {
            int ch = getch();
            int new_x = player_x;
            int new_y = player_y;
            switch (ch) {
                case 'w':  // 向上移动
                    new_x--;
                    break;
                case 's':  // 向下移动
                    new_x++;
                    break;
                case 'a':  // 向左移动
                    new_y--;
                    break;
                case 'd':  // 向右移动
                    new_y++;
                    break;
                default:
                    break;
            }
            // 检查新位置是否在迷宫范围内，并且是通路(maze[new_x][new_y]==0)
            if (new_x >= 0 && new_x < MAZESIZE &&
                new_y >= 0 && new_y < MAZESIZE &&
                maze[new_x][new_y] == 0) {
                player_x = new_x;
                player_y = new_y;
            }
        }
        // 为了避免 CPU 占用过高，暂停 50 毫秒
        usleep(50000);
    }
}

// --------------------- 线程函数 ---------------------
void *displayThread(void *arg) {
    showMap();
    return NULL;
}

void *controlThread(void *arg) {
    controlPlayer();
    return NULL;
}
